using System;
using System.Collections.Generic;
using System.Linq;

namespace MathSharp
{
	public enum ValueType {
		/// <summary>
		/// число
		/// </summary>
		Int,
		/// <summary>
		/// число с плавоющей точкой
		/// </summary>
		Double,
		/// <summary>
		/// строка
		/// </summary>
		String,
		/// <summary>
		/// логическое
		/// </summary>
		Bool,
		/// <summary>
		/// масив
		/// </summary>
		Array,
		/// <summary>
		/// пара ключ-значение
		/// </summary>
		KeyValuePair,
		/// <summary>
		/// словарь
		/// </summary>
		Dictionary,
		/// <summary>
		/// куб (многомерная структура)
		/// </summary>
		Cube,
		
		/// <summary>
		/// Null значение
		/// </summary>
		Null,
		/// <summary>
		/// не определённое значение
		/// </summary>
		Variable,
		/// <summary>
		/// Пустое значение для возврата из функций
		/// </summary>
		Void
	}
	
	[Flags]
	public enum ValueDirectionType {
		None = 0,
		In = 1,
		Out = 2,
		InOut = 3
	}
	
	public class ListFragment<T>: List<T> {
		int shiftLines;
		
		public ListFragment(): base() {
		}
		
		public ListFragment(IEnumerable<T> source, int from, int to) {
			//Console.WriteLine("Create ListFragment. from = {0}, to = {1}. res: ",
			//                  from, to);
			if (to < from)
				throw new ArgumentException("Позиция окончания фрагмента ({1}) находится в списке раньше позиции начала ({0}) фрагмента".format(from, to));
			int length = to - from + 1;
			IEnumerable<T> msource = source;
			if (from > 0)
				msource = msource.Skip(from);
			if (to < source.Count())
				msource = msource.Take(length);
			AddRange(msource);
			if (source is ListFragment<T>) 
				shiftLines = ((ListFragment<T>)source).GetOriginalLine(0);
			else
				shiftLines = 0;
			//Console.WriteLine(this.Select(line => string.Concat("    ", line)).Join("\r\n"));
		}
		
		public int GetOriginalLine(int line) {
			return line + shiftLines;
		}
	}
	
	public delegate bool Predicate<T1, T2>(T1 arg1, T2 arg2);
}

